package com.example.myapp;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;

import androidx.annotation.Nullable;

public class GameView extends View {
    private static final int FLOOR = 0, WALL = 1, BOX = 2, TARGET = 3, PEOPLE = 4, Box_In_Target = 5;
    public static int cellHeight;
    private Paint mPaint = new Paint();
    private int level = 1;
    private int[][] map = MapData.getMap(level);
    private Bitmap floorBitmap, wallBitmap, boxBitmap, targetBitmap, peopleBitmap, boxInTargetBitmap;
    private Rect srcFloorRect, srcWallRect, srcBoxRect, srcTargetRect, srcPeopleRect, srcBoxInTarget;
    private Man man = new Man();
    private int lastMapType = 0;
    public OnWinListener onWinListener;

    public GameView(Context context) {
        super(context);
    }

    public GameView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        floorBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.floor);
        srcFloorRect = new Rect(0, 0, floorBitmap.getWidth(), floorBitmap.getHeight());
        wallBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.wall);
        srcWallRect = new Rect(0, 0, wallBitmap.getWidth(), wallBitmap.getHeight());
        boxBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.box);
        srcBoxRect = new Rect(0, 0, boxBitmap.getWidth(), boxBitmap.getHeight());
        targetBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.target);
        srcTargetRect = new Rect(0, 0, targetBitmap.getWidth(), targetBitmap.getHeight());
        peopleBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.people);
        srcPeopleRect = new Rect(0, 0, peopleBitmap.getWidth(), peopleBitmap.getHeight());
        boxInTargetBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.success);
        srcBoxInTarget = new Rect(0, 0, boxInTargetBitmap.getWidth(), boxInTargetBitmap.getHeight());
    }

    public void setOnWinListener(OnWinListener onWinListener) {
        this.onWinListener = onWinListener;
    }

    public void setLevel(int level) {
        this.level = level;
        map = MapData.getMap(level);
        postInvalidate();
    }

    @Override
    protected void onDraw(Canvas canvas) {
        int width = getMeasuredWidth();
        int height = getMeasuredHeight();
        cellHeight = width / map[0].length;
        mPaint.setColor(Color.BLACK);
        mPaint.setStrokeWidth(2);
        if ((width > height && map.length > map[0].length) || width < height && map.length < map[0].length) {
            map = mapRotate(map);
            postInvalidate();
        }

        for (int i = 0; i <= map.length; i++) {
            canvas.drawLine(0, cellHeight * i, cellHeight * map[0].length, cellHeight * i, mPaint);
        }

        for (int i = 0; i <= map[0].length; i++) {
            canvas.drawLine(cellHeight * i, 0, cellHeight * i, cellHeight * map.length, mPaint);
        }
        int boxNum = 0;
        for (int i = 0; i < map.length; i++) {  //画地图
            for (int j = 0; j < map[0].length; j++) {
                Rect dest = new Rect(cellHeight * j, cellHeight * i, cellHeight * (j + 1), cellHeight * (i + 1));
                if (map[i][j] == FLOOR) {
                    canvas.drawBitmap(floorBitmap, srcFloorRect, dest, mPaint);
                } else if (map[i][j] == WALL) {
                    canvas.drawBitmap(wallBitmap, srcWallRect, dest, mPaint);
                } else if (map[i][j] == PEOPLE) {
                    canvas.drawBitmap(peopleBitmap, srcPeopleRect, dest, mPaint);
                    man.setRow(i);
                    man.setCol(j);
                } else if (map[i][j] == BOX) {
                    canvas.drawBitmap(boxBitmap, srcBoxRect, dest, mPaint);
                    boxNum++;
                } else if (map[i][j] == TARGET) {
                    canvas.drawBitmap(targetBitmap, srcTargetRect, dest, mPaint);
                } else if (map[i][j] == Box_In_Target) {
                    canvas.drawBitmap(boxInTargetBitmap, srcBoxInTarget, dest, mPaint);
                }
            }
        }
        checkWin(boxNum);
    }

    private void checkWin(int boxNum) {
        if (boxNum == 0) {
            if (onWinListener != null)
                onWinListener.onWin();
        }
    }


    private int[][] mapRotate(int[][] map) {
        int[][] temp = new int[map[0].length][map.length];
        for (int i = 0; i < map[0].length; i++) {
            for (int j = 0; j < map.length; j++) {
                temp[i][j] = map[j][i];
            }
        }
        return temp;
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        int touchX = (int) event.getX();
        int touchY = (int) event.getY();
        // Log.v("1",touchX+"---"+touchY);

        Rect[] surroundRects = man.getSurroundRects();
        int i = 0;
        for (; i < 4; i++) {
            if (surroundRects[i].contains(touchX, touchY))
                break;
        }

        if (i == 4)
            return true;

        int[][] offset = new int[][]{
                {-1, 0},
                {0, 1},
                {1, 0},
                {0, -1}
        };

        int moveToRow = man.getRow() + offset[i][0];
        int moveToCol = man.getCol() + offset[i][1];
        if (map[moveToRow][moveToCol] == FLOOR) {
            map[moveToRow][moveToCol] = PEOPLE;
            map[man.getRow()][man.getCol()] = lastMapType;
            lastMapType = 0;
        } else if (map[moveToRow][moveToCol] == BOX) {
            int boxMoveRow = moveToRow + offset[i][0];
            int boxMoveCol = moveToCol + offset[i][1];
            if (map[boxMoveRow][boxMoveCol] == FLOOR) {
                map[moveToRow][moveToCol] = PEOPLE;
                map[man.getRow()][man.getCol()] = FLOOR;
                map[boxMoveRow][boxMoveCol] = BOX;
            } else if (map[boxMoveRow][boxMoveCol] == TARGET) {
                map[moveToRow][moveToCol] = PEOPLE;
                map[man.getRow()][man.getCol()] = FLOOR;
                map[boxMoveRow][boxMoveCol] = Box_In_Target;
            }

        } else if (map[moveToRow][moveToCol] == TARGET) {
            lastMapType = TARGET;
            map[moveToRow][moveToCol] = PEOPLE;
            map[man.getRow()][man.getCol()] = FLOOR;
        }
        /*for(int count = 0;count<map.length;count++){      //用于测试MapData 数据是否改变
            for(int ccc = 0;ccc<map[count].length;ccc++){
                System.out.print(map[count][ccc]+" ");
            }
            System.out.println("\n");
        }
        int[][] a = MapData.getMap1();
        for(int count = 0;count<map.length;count++){
            for(int ccc = 0;ccc<map[count].length;ccc++){
                System.out.print(a[count][ccc]+" ");
            }
            System.out.println("\n");
        }*/
        //System.out.println(map);
        //System.out.println(MapData.getMap(1)); //测试getmap 和 map 的地址得出 map指向MapData对象
        postInvalidate();
        return true;
    }

    public interface OnWinListener {
        void onWin();
    }

}
